﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Datorgrafik_lab1.Models;
using Microsoft.Xna.Framework.Graphics;
using Datorgrafik_lab1.Helpers;

namespace Datorgrafik_lab1.Objects {
    public class City : GameObject
    {
        //City variables
        private float SizeX = 700f;
        private float SizeZ = 700f;
        private int numBuildings = 2000;
        private float buildingMaxHeight = 80f;
        private float buildingMinHeight = 4f;
        private float buildingMaxWidth = 4f;
        private float buildingMinWidth = 2f;
        private float buildingMaxLength = 4f;
        private float buildingMinLength = 2f;

        Random random = new Random();

        List<Color> buildingColors = new List<Color>() {            
            Color.Red,
            Color.Black,
            Color.Gray,
            Color.DarkBlue
        };

        public City(GraphicsDevice graphics, Vector3 pos, float scale)
            : base(graphics, pos, Quaternion.Identity, scale)
        {
            
        }

        protected override void InitializeModel() {
            vertices = new VertexPositionColor[this.numBuildings * 8];
            //30 indices for 10 triangles, every side except bottom
            indices = new int[this.numBuildings * 30];

            int verticeCounter = 0;
            int indiceCounter = 0;

            int FTR = 0;
            int FTL = 1;
            int FBR = 2;
            int FBL = 3;
            int BTR = 4;
            int BTL = 5;
            int BBR = 6;
            int BBL = 7;

            for(int x = 0; x < this.numBuildings; x++) {
                CubeVerticePositions cvp = newBuildingVertices();
                Color color = getColor();

                FTR = verticeCounter;
                FTL = verticeCounter + 1;
                FBR = verticeCounter + 2;
                FBL = verticeCounter + 3;
                BTR = verticeCounter + 4;
                BTL = verticeCounter + 5;
                BBR = verticeCounter + 6;
                BBL = verticeCounter + 7;

                //Front Top right
                vertices[FTR] = new VertexPositionColor(cvp.FrontTopRight, color);

                //Front top left
                vertices[FTL] = new VertexPositionColor(cvp.FrontTopLeft, color);

                //Front bottom right
                vertices[FBR] = new VertexPositionColor(cvp.FrontBottomRight, color);

                //Front bottom left
                vertices[FBL] = new VertexPositionColor(cvp.FrontBottomLeft, color);

                //Back Top right
                vertices[BTR] = new VertexPositionColor(cvp.BackTopRight, color);

                //Back top left
                vertices[BTL] = new VertexPositionColor(cvp.BackTopLeft, color);

                //Back bottom right
                vertices[BBR] = new VertexPositionColor(cvp.BackBottomRight, color);

                //Back bottom left
                vertices[BBL] = new VertexPositionColor(cvp.BackBottomLeft, color);

                //Front triangle 1 (bottom portion) |\
                indices[indiceCounter] = FTL; //top left;
                indices[indiceCounter + 1] = FBR; // bottom right;
                indices[indiceCounter + 2] = FBL; // bottom left;

                //Front Triangle 2 (top portion) \|
                indices[indiceCounter + 3] = FTL; // top left;
                indices[indiceCounter + 4] = FTR; // top right;
                indices[indiceCounter + 5] = FBR; // bottom right;

                //Back triangle 1 (bottom portion) |\
                indices[indiceCounter + 6] = BTL; //top left;
                indices[indiceCounter + 8] = BBR; // bottom right;
                indices[indiceCounter + 7] = BBL; // bottom left;

                //Back Triangle 2 (top portion) \|
                indices[indiceCounter + 9] = BTL; // top left;
                indices[indiceCounter + 11] = BTR; // top right;
                indices[indiceCounter + 10] = BBR; // bottom right;

                //LEFT triangle 1 (bottom portion) |\
                indices[indiceCounter + 12] = BTL; //top left;
                indices[indiceCounter + 13] = FBL; // bottom right;
                indices[indiceCounter + 14] = BBL; // bottom left;

                //LEFT Triangle 2 (top portion) \|
                indices[indiceCounter + 15] = BTL; // top left;
                indices[indiceCounter + 16] = FTL; // top right;
                indices[indiceCounter + 17] = FBL; // bottom right;

                //RIGHT triangle 1 (bottom portion) |\
                indices[indiceCounter + 18] = BTR; //top left;
                indices[indiceCounter + 20] = FBR; // bottom right;
                indices[indiceCounter + 19] = BBR; // bottom left;

                //RIGHT Triangle 2 (top portion) \|
                indices[indiceCounter + 21] = BTR; // top left;
                indices[indiceCounter + 23] = FTR; // top right;
                indices[indiceCounter + 22] = FBR; // bottom right;

                //TOPP triangle 1 (bottom portion) |\
                indices[indiceCounter + 24] = BTL; //top left;
                indices[indiceCounter + 25] = FTR; // bottom right;
                indices[indiceCounter + 26] = FTL; // bottom left;

                //TOPP Triangle 2 (top portion) \|
                indices[indiceCounter + 27] = BTL; // top left;
                indices[indiceCounter + 28] = BTR; // top right;
                indices[indiceCounter + 29] = FTR; // bottom right;

                verticeCounter += 8;
                indiceCounter += 30;
            }

        }

        #region Helpers
        private Color getColor() {
            return this.buildingColors[random.Next(0, this.buildingColors.Count)];
        }
        private double GenRand(double one, double two) {
            return one + random.NextDouble() * (two - one);
        }
        private Vector3 randomPosition() {
            return new Vector3(
                this.Position.X + (float)GenRand(-(double)this.SizeX, (double)this.SizeX),
                this.Position.Y,
                this.Position.Z + (float)GenRand(-(double)this.SizeZ, (double)this.SizeZ));
        }
        private CubeVerticePositions newBuildingVertices() {
            float height = (float)GenRand((double)this.buildingMinHeight, (double)this.buildingMaxHeight);
            float length = (float)GenRand((double)this.buildingMinLength, (double)this.buildingMaxLength);
            float width = (float)GenRand((double)this.buildingMinWidth, (double)this.buildingMaxWidth);

            return new CubeVerticePositions(randomPosition(), width, height, length);
        }
        #endregion
    }
}
